<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    /*
    * 记忆函数：用空间换时间，用一些数据结构保存计算的结果，有类似的计算，直接取已有的数据
    *
    * */

    //代理缓存
    //主体
    function add(a,b){
        //大量复杂的计算，需要大量的时间
        return a + b
    }

    //代理
    function memorize(fn){ //接收一个函数
        var cache = {} //数据结构容器，保存计算结果
        return function (){ //代理中返回的函数，可以设置接收的形参个数，也可以直接用arguments
            //创建一个独一无二的标志，表示已经计算过的凭证
            //因为arguments没有join方法，call对象冒充，使得arguments对象拥有array对象的join方法
            var key = Array.prototype.join.call(arguments,",")

            if(key in cache){ //如果已经计算过了，有数据
                console.log("缓存")
                return cache[key] //数据结构的示例{"1,1":2,"1,2":3} key就是对象中对应的属性名
            }else{ //否则就是首次计算
                console.log("计算")
                return cache[key] = fn.apply(this,arguments) //将计算的结果保存到缓存中
            }
        }
    }

    var memorizeAdd = memorize(add) //调用代理，将主题函数传入代理，最后返回一个函数
    //下面都是操作代理
    memorizeAdd(1,1) //计算
    memorizeAdd(1,1) //缓存
    memorizeAdd(1,2) //计算
</script>
</body>
</html>